import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.*;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Monitor implements Listener {

    private FileConfiguration config;
    private JavaPlugin plugin;

    public Monitor(FileConfiguration config,JavaPlugin plugin) {
        this.config = config;
        this.plugin = plugin;
    }

    @EventHandler
    public void onPlayerJoinEvent(PlayerJoinEvent e) {
        e.setJoinMessage(null);
        Bukkit.broadcastMessage("§e玩家§f " + e.getPlayer().getName() + " §e上线了");
    }

    @EventHandler
    public void onPlayerQuitEvent(PlayerQuitEvent e) {
        e.setQuitMessage(null);
        Bukkit.broadcastMessage("§e玩家§f " + e.getPlayer().getName() + " §e下线了");
    }

    @EventHandler
    public void onAsyncPlayerChatEvent(AsyncPlayerChatEvent e) {
        try {
            {
                String msg = e.getMessage();
                Pattern p = Pattern.compile("&[0-9a-f]");
                Matcher m = p.matcher(msg);
                while (m.find()) {
                    String target = m.group();
                    String result = target.replace("&", "§");
                    msg = msg.replace(target, result);
                }
                e.setMessage(msg);
            }
            {
                Pattern p = Pattern.compile("@(\\w+)?\\s?");
                Matcher m = p.matcher(e.getMessage());
                while (m.find()) {
                    String target = m.group();
                    Player player = Bukkit.getPlayerExact(target.substring(1).replace(" ", ""));
                    if (player != null) {
                        e.setMessage(e.getMessage().replace(target, "§b" + target + "§r"));
                        player.playNote(player.getLocation(), Instrument.BELL, Note.natural(1, Note.Tone.A));
                    }
                }
            }
            String world = "";
            switch (e.getPlayer().getLocation().getWorld().getName()) {
                case "world":
                    world = "§7[§2生存§7]";
                    break;
                case "world_nether":
                    world = "§7[§4下界§7]";
                    break;
                case "world_the_end":
                    world = "§7[§5末地§7]";
                    break;
                default:
                    world = "§7[§8未知§7]";
                    System.out.println(e.getPlayer().getLocation().getWorld().getName());
            }

            String nick = RedisInstance.getInstance().getNick(e.getPlayer().getName());
            String prefix = RedisInstance.getInstance().getPrefix(e.getPlayer().getName());
            String suffix = RedisInstance.getInstance().getSuffix(e.getPlayer().getName());
            String name = "§r" + (prefix == null ? "" : prefix) + "§7<" + "§r" + (nick == null ? "%1$s" : nick) + "§7>" ;
            String content = "§r%2$s";
            e.setFormat(world + name + content);
        } catch (Exception err) {
            Bukkit.getConsoleSender().sendMessage("§f[§aRedenTreasure§f]§4发言监听异常");
        }
    }


    @EventHandler
    public void onPlayerDeathEvent(PlayerDeathEvent e) {
        try {
            if (config.getBoolean("back.enable")) {
                Player player = e.getEntity();
                Location location = player.getLocation();
                new BukkitRunnable() {
                    @Override
                    public void run() {
                        RedisInstance.getInstance().setBack(player.getName());
                    }
                }.runTaskAsynchronously(plugin);
            }
        } catch (Exception err) {
            Bukkit.getConsoleSender().sendMessage("§f[§aRedenTreasure§f]§4死亡监听异常");
        }
    }

    @EventHandler
    public void onPlayerRespawnEvent(PlayerRespawnEvent e) {
        try {
            if (config.getBoolean("respawn-limit.enable")) {
                Player player = e.getPlayer();
                new BukkitRunnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1);
                            player.setHealth(config.getInt("respawn-limit.health"));
                            player.setFoodLevel(config.getInt("respawn-limit.food"));
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                    }
                }.runTaskAsynchronously(plugin);
            }
        } catch (Exception err) {
            Bukkit.getConsoleSender().sendMessage("§f[§aRedenTreasure§f]§4重生监听异常");
        }
    }

    @EventHandler
    public void onItemSpawnEvent(ItemSpawnEvent e) {
        if (config.getBoolean("drop-highlight.enable")) {
            Item item = e.getEntity();
            item.setGlowing(true);
        }
    }

    @EventHandler
    public void onInventoryClickEvent(InventoryClickEvent e) {
        try {
            //Inventory inv = e.getInventory();
            Player player = (Player) e.getWhoClicked();
            net.minecraft.server.v1_16_R3.ItemStack nms = CraftItemStack.asNMSCopy(e.getCurrentItem());
            if (nms.hasTag()) {
                if (nms.getTag().hasKey("Tag"))
                    if (nms.getTag().getString("Tag").equals("MenuItem"))
                        player.closeInventory();
                if (!e.isShiftClick() && e.isLeftClick() && nms.getTag().hasKey("Left"))
                    player.chat(nms.getTag().getString("Left"));
                if (!e.isShiftClick() && e.isRightClick() && nms.getTag().hasKey("Right"))
                    player.chat(nms.getTag().getString("Right"));
                if (e.isShiftClick() && e.isLeftClick() && nms.getTag().hasKey("LeftS"))
                    player.chat(nms.getTag().getString("LeftS"));
                if (e.isShiftClick() && e.isRightClick() && nms.getTag().hasKey("RightS"))
                    player.chat(nms.getTag().getString("RightS"));
                if (nms.getTag().hasKey("Tag"))
                    if (nms.getTag().getString("Tag").equals("MenuItem"))
                        e.setCancelled(true);
                if (nms.getTag().hasKey("Tag") && nms.getTag().getString("Tag").equals("QuestItem")) {
                    String factor = nms.getTag().getString("Factor");
                    String reward = nms.getTag().getString("Reward");
                    Inventory inventory = player.getInventory();
                    ItemStack itemFactor = new ItemStack(Material.matchMaterial(factor.substring(0, factor.lastIndexOf(" "))), Integer.valueOf(factor.substring(factor.lastIndexOf(" ") + 1)));
                    ItemStack itemReward = new ItemStack(Material.matchMaterial(reward.substring(0, reward.lastIndexOf(" "))), Integer.valueOf(reward.substring(reward.lastIndexOf(" ") + 1)));
                    if (inventory.contains(itemFactor)) {
                        inventory.removeItem(itemFactor);
                        inventory.addItem(itemReward);
                        player.sendMessage("§e兑换成功");
                    } else {
                        player.sendMessage("§4未满足兑换条件");
                    }
                    e.setCancelled(true);
                }
            }
        } catch (Exception err) {
            Bukkit.getConsoleSender().sendMessage("§f[§aRedenTreasure§f]§4物品栏点击监听异常");
        }
    }

    @EventHandler
    public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent e) {
        try {
            if (config.getBoolean("damage-view.enable")) {
                if (e.getFinalDamage() > 0) {
                    if (e.getEntity() instanceof Player) {
                        Player player = (Player) e.getEntity();
                        String damager = e.getDamager().getScoreboardTags().isEmpty() ? Nms.getEntityName(e.getDamager().getType().toString()) : Nms.getEntityName(e.getDamager().getScoreboardTags().toArray()[0].toString());
                        if (damager.equalsIgnoreCase("PLAYER"))
                            damager = e.getDamager().getName();
                        player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent("§4" + damager + " §f对你造成了 §4" + new DecimalFormat("#.##").format(e.getFinalDamage()) + " §f点伤害"));
                    }
                    if (e.getDamager() instanceof Player) {
                        Player player = (Player) e.getDamager();
                        String holder = Nms.getEntityName(e.getEntity().getType().toString());
                        if (holder.equalsIgnoreCase("PLAYER"))
                            holder = e.getEntity().getName();
                        player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent("§f你对 §4" + holder + " §f造成了 §4" + new DecimalFormat("#.##").format(e.getFinalDamage()) + " §f点伤害"));
                    }
                    if (!e.getDamager().getScoreboardTags().isEmpty()) {
                        if (Bukkit.getPlayer(e.getDamager().getScoreboardTags().toArray()[0].toString()) != null) {
                            Player player = Bukkit.getPlayer(e.getDamager().getScoreboardTags().toArray()[0].toString());
                            String holder = e.getEntity() instanceof Player ? e.getEntity().getName() : Nms.getEntityName(e.getEntity().getType().toString());
                            player.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent("§f你对 §4" + holder + " §f造成了 §4" + new DecimalFormat("#.##").format(e.getFinalDamage()) + " §f点伤害"));
                        }
                    }
                }
            }
        } catch (Exception err) {
            Bukkit.getConsoleSender().sendMessage("§f[§aRedenTreasure§f]§4实体受伤监听异常");
        }
    }

    @EventHandler
    public void onProjectileLaunchEvent(ProjectileLaunchEvent e) {
        try {
            if (config.getBoolean("damage-view.enable")) {
                if (e.getEntity().getShooter() instanceof Player) {
                    e.getEntity().addScoreboardTag(((Player) e.getEntity().getShooter()).getName());
                } else {
                    e.getEntity().addScoreboardTag(((Entity) e.getEntity().getShooter()).getType().toString());
                }
            }
        } catch (Exception err) {
            try {
                e.getEntity().addScoreboardTag("DISPENSER");
            } catch (Exception err2) {
                Bukkit.getConsoleSender().sendMessage("§f[§aRedenTreasure§f]§4投掷物生成监听异常");
            }
        }
    }
}
